package com.mairuide._frame.config;

import com.mairuide._frame.exception.*;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Resource
	private UserDetailServiceImpl userDetailService;
	
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailService).passwordEncoder(new PasswordEncoder() {
			
			Md5PasswordEncoder encoder = new Md5PasswordEncoder();
			@Override
			public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
				return encoder.encodePassword(rawPass, null).equals(encPass);
			}
			
			@Override
			public String encodePassword(String rawPass, Object salt) {
				return encoder.encodePassword(rawPass, null);
			}
		});
	}
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http
		// 配置登录
		.formLogin()
			.loginPage("/login").loginProcessingUrl("/login")
			.usernameParameter("loginname").passwordParameter("password")
			.defaultSuccessUrl("/", true)
			.failureHandler(new AuthenticationFailureHandler() {
				
				@Override
				public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
						AuthenticationException exception) throws IOException, ServletException {
					String strUrl = null;
					if (exception instanceof DisabledException) {
			        	strUrl = request.getContextPath() + "/login?disabled";
			        } else if (exception instanceof UsernameNotFoundException) {
			        	strUrl = request.getContextPath() + "/login?notfound";
			        } else if (exception instanceof BadCredentialsException) {
			        	strUrl = request.getContextPath() + "/login?badcredentials";
			        } else if (exception.getCause() instanceof TimeExpireException) {
						strUrl = request.getContextPath() + "/login?timeexpire";
					} else if (exception.getCause() instanceof VIPException) {
						strUrl = request.getContextPath() + "/login?viperro";
					} else if (exception.getCause() instanceof AuthorizationCodeException) {
						strUrl = request.getContextPath() + "/login?authcodeerro";
					} else if (exception.getCause() instanceof DiskException) {
						strUrl = request.getContextPath() + "/login?diskerro";
					} else if (exception.getCause() instanceof TimeNotFoundException) {
						strUrl = request.getContextPath() + "/login?timenotfound";
					} else {
			        	strUrl = request.getContextPath() + "/login?error";
			        }
					response.sendRedirect(strUrl);
				}
			})
		// 配置退出
		.and().logout()
			.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
		// 配置请求拦截
		.and().authorizeRequests()
			.antMatchers("/login**").permitAll()
			.antMatchers("/logout**").permitAll()
			.anyRequest().authenticated()
			.and().headers().frameOptions().disable()
		// 配置是否启用CSFF
		.and().csrf()
			.disable();
		
		
	}
	
	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers("/bower_components/**","/imgs/**","/cus/**","/dist/**","/plugins/**","/wxserver/**","/h5/**","/plat/**","/file/**","/map/**");
	}
}
